<?php

/**
 * 后台权限列表，基于RBAC原理设计，请先了解它
 *
 * @author jiang
 */

namespace Kj\Admin\Controller;

use View, Scstore, Input, Redirect, Config, Auth, Lang, Response, Request, Hash, URL, Validator;
use Kj\Admin\Controller\AdminController;
use Kj\Admin\Libraries\Acl;
use Kj\Admin\Libraries\Tree;
use Kj\Admin\Models\User;
use Kj\Admin\Models\Group;
use Kj\Admin\Models\Permission;
use Kj\Admin\Models\Access;
use Kj\Admin\Libraries\Js;
use Kj\Admin\Validator\Acl as AclValidator;

class AclController extends AdminController
{
    /**
     * 用户权限节点表模型操作对象
     *
     * @var object
     */
    protected $permission, $access, $user, $group, $acl;

    /**
     * 初始化，实例化权限表数据操作对象
     *
     * @access public
     */
    public function __construct()
    {
        parent::__construct();
        $this->permission = new Permission();
        $this->access = new Access();
        $this->user = new User();
        $this->group = new Group();
        $this->acl = new Acl();
    }

    /**
     * 显示权限列表首页
     *
     * @access public
     */
    public function index()
    {
        $list = $this->permission->getAllAccessPermissionByPage();
        $page = $this->permission->page();
        return View::make('admin/acl/index')->with(compact('list', 'page'));
    }

    /**
     * 增加权限功能
     *
     * @access public
     */
    public function add()
    {
        if(Request::method() == 'POST') return $this->_savePermissionToDatabase();
        $formUrl = U('admin/acl/add');
        $list = $this->permission->getAllAccessPermission();
        $list = (array) Tree::genTree($list);
        $select = Tree::dropDownSelect($list);
        return View::make('admin/acl/add')->with(compact('select', 'formUrl'));
    }

    /**
     * 增加功能权限入库处理
     *
     * @access private
     */
    private function _savePermissionToDatabase()
    {
        //确保参数正确
        $data = Input::get('data', false);
        if( ! $data or ! is_array($data)) return Js::error(Lang::get('bk.info_incomplete'));

        //表单验证
        $validator = new AclValidator();
        if( ! $validator->add($data))
        {
            return Js::error($validator->getMsg());
        }
        
        //检测是否已经存在
        if($this->permission->checkIfIsExists($data['module'], $data['class'], $data['action']))
        {
            return Js::error(Lang::get('bk.acl_exists'));
        }
        
        //增加的时间
        $data['add_time'] = time();

        //标志当前属于第几级菜单
        $info = $this->permission->getOnePermissionById(intval($data['pid']));
        $data['level'] = $info['level'] + 1;

        //入库
        if($this->permission->addPermission($data) !== false)
        {
            return Js::locate(URL::to('admin/acl/index'), 'parent');
        }
        return Js::error(Lang::get('bk.action_error'));
    }
    
    /**
     * 删除权限功能
     *
     * @access public
     * @todo 只能删除自己所拥有的权限？有没有必要做？
     */
    public function delete()
    {
        $id = Input::get('id', false);
        if( ! $id) return responseJson(Lang::get('bk.action_error'));
        if( ! is_array($id)) $id = array($id);
        if($this->permission->deletePermission($id) !== false)
        {
            return responseJson(Lang::get('bk.action_success'), true);
        }
        return responseJson(Lang::get('bk.action_error'));
    }
    
    /**
     * 编辑权限功能
     *
     * @access public
     */
    public function edit()
    {
        if(Request::method() == 'POST') return $this->_updatePermissionToDatabase();
        
        //确保参数正确
        $id = Input::get('id', false);
        if( ! $id or ! is_numeric($id)) return Js::error(Lang::get('bk.illegal_operation'));
        
        //父级功能菜单列表
        $list = $this->permission->getAllAccessPermission();
        $list = (array) Tree::genTree($list);
        
        //是否存在
        $permissionInfo = $this->permission->getOnePermissionById(intval($id));
        if(empty($permissionInfo))
        {
            return Js::error(Lang::get('bk.acl_not_found'), true);
        }
        
        //生成下拉表单
        $select = Tree::dropDownSelect($list, $permissionInfo['pid']);
        $formUrl = U('admin/acl/edit');
        
        return View::make('admin/acl/add')->with(
                compact('select', 'permissionInfo', 'formUrl', 'id')
            );
    }
    
    /**
     * 编辑功能权限入库处理
     *
     * @access private
     */
    private function _updatePermissionToDatabase()
    {
        $data = Input::get('data', false);
        if( ! $data) return Js::error(Lang::get('info_incomplete'));
        
        //确保参数正确传入
        $id = intval($data['id']);
        if( ! $id or ! is_numeric($id))
        {
            return Js::error(Lang::get('bk.illegal_operation'));
        }
        
        //删除不需要更新的信息
        unset($data['id']);
        
        //表单验证
        $validator = new AclValidator();
        if( ! $validator->add($data))
        {
            return Js::error($validator->getMsg());
        }
        
        //检测是否已经存在
        if($this->permission->checkIfIsExists($data['module'], $data['class'], $data['action'], false, $id))
        {
            return Js::error(Lang::get('bk.acl_exists'));
        }
        
        //标志当前属于第几级菜单
        $info = $this->permission->getOnePermissionById(intval($data['pid']));
        $data['level'] = $info['level'] + 1;
        
        //入库
        if($this->permission->editPermission($data, intval($id)) !== false)
        {
            return Js::locate(URL::to('admin/acl/index'), 'parent');
        }
        return Js::error(Lang::get('bk.action_error'));
    }
    
    /**
     * 排序权限功能
     *
     * @access public
     */
    public function sort()
    {
        $sort = Input::get('sort', false);
        if( ! $sort or ! is_array($sort)) return Js::error(Lang::get('bk.choose_checked'));
        
        foreach($sort as $key => $value)
        {
            if($this->permission->sortPermission($key, $value) === false) $err = true;
        }
        
        if(isset($err)) return Js::error(Lang::get('bk.action_error'));
        
        return Js::locate(URL::to('admin/acl/index'), 'parent');
    }

    /**
     * 对用户进行权限设置
     * 
     * @access public
     */
    public function user()
    {
        if(Request::method() == 'POST') return $this->_saveUserPermissionToDatabase();

        //取得用户的ID，确保参数正确
        $id = Input::get('id', false);
        if( ! $id or ! is_numeric($id)) return Js::error(Lang::get('bk.illegal_operation'));
        
        //用户信息
        $info = $this->user->getOneUserById(intval($id));
        if(empty($info)) return Js::error(Lang::get('bk.illegal_operation'));
        
        //判断当前用户有没有权限进行这个操作
        if( ! $this->acl->checkGroupLevelPermission($id))
        {
            return Js::error(Lang::get('bk.account_level_deny'), true);
        }

        //分菜单来查询
        $pid = intval(Input::get('pid', false));
        
        //取回用户所拥有的权限列表
        $list = (array) Scstore::getUserPermissionSession();
        $tree = Tree::genPermissionTree($list);

        //当前用户的权限
        $userAcl = $this->access->getUserAccessPermission(intval($id));
        $hasPermissions = array();
        foreach($userAcl as $key => $value)
        {
            $hasPermissions[] = $value['permission_id'];
        }

        return View::make('admin/acl/setpermission')->with(
                compact('tree', 'hasPermissions', 'id', 'info', 'pid')
            );
    }

    /**
     * 用户权限入库
     * 
     * @return boolean true|false
     */
    private function _saveUserPermissionToDatabase()
    {
        $permissions = Input::get('permission', array());
        $id = Input::get('id', false);
        $all = Input::get('all', false);
        
        //判断当前用户有没有权限进行这个操作
        if( ! $this->acl->checkGroupLevelPermission($id))
        {
            return Js::error(Lang::get('bk.account_level_deny'));
        }

        //确保参数的正确性
        if( ! $id or ! is_numeric($id) or ! $all) return Js::error(Lang::get('bk.illegal_operation'));

        //当前列表中的所有权限信息
        $allArr = explode(',', $all);
        $allArr = array_map('intval', $allArr);
        
        //需要作更改的权限信息
        $permission = array_unique($permissions);

        //入库
        $ret = $this->access->setPermission($permission, intval($id), $allArr, 2);
        if($ret) return Js::error(Lang::get('bk.action_success'));
        return Js::error(Lang::get('bk.action_error'));
    }
    
    /**
     * 对用户组进行权限设置
     * 
     * @access public
     */
    public function group()
    {
        if(Request::method() == 'POST') return $this->_saveGroupPermissionToDatabase();

        //取得用户组的ID，确保参数正确
        $id = Input::get('id', false);
        if( ! $id or ! is_numeric($id)) return Js::error(Lang::get('bk.illegal_operation'));
        
        //用户组信息
        $info = $this->group->getOneGroupById(intval($id));
        if(empty($info)) return Js::error(Lang::get('bk.illegal_operation'));
        
        //判断当前用户有没有权限进行这个操作
        if( ! $this->acl->checkGroupLevelPermission($id, false))
        {
            return Js::error(Lang::get('bk.account_level_deny'), true);
        }

        //分菜单来查询
        $pid = intval(Input::get('pid', false));
        
        //取回用户组所拥有的权限列表
        $list = (array) Scstore::getUserPermissionSession();
        $tree = Tree::genPermissionTree($list);

        //当前用户组的权限
        $groupAcl = $this->access->getGroupAccessPermission(intval($id));
        $hasPermissions = array();
        foreach($groupAcl as $key => $value)
        {
            $hasPermissions[] = $value['permission_id'];
        }

        return View::make('admin/acl/setpermission')->with(
                compact('tree', 'hasPermissions', 'id', 'info', 'pid')
            );
    }

    /**
     * 用户组权限入库
     * 
     * @return boolean true|false
     */
    private function _saveGroupPermissionToDatabase()
    {
        $permissions = Input::get('permission', array());
        $id = Input::get('id', false);
        $all = Input::get('all', false);
        
        //确保参数的正确性
        if( ! $id or ! is_numeric($id) or ! $all) return Js::error(Lang::get('bk.illegal_operation'));
        
        //判断当前用户有没有权限进行这个操作
        if( ! $this->acl->checkGroupLevelPermission($id, false))
        {
            return Js::error(Lang::get('bk.account_level_deny'));
        }

        //当前列表中的所有权限信息
        $allArr = explode(',', $all);
        $allArr = array_map('intval', $allArr);
        
        //需要作更改的权限信息
        $permission = array_unique($permissions);

        //入库
        $ret = $this->access->setPermission($permission, intval($id), $allArr, 1);
        if($ret) return Js::error(Lang::get('bk.action_success'));
        return Js::error(Lang::get('bk.action_error'));
    }

}